package evo;

import java.io.File;
import java.util.Vector;

import opt.FitnessFunction;

import ns2.Topology;

import util.FileReader;
import util.SSIDException;

import ids.Sensor;

import ec.EvolutionState;
import ec.Individual;
import ec.Problem;
import ec.simple.SimpleFitness;
import ec.simple.SimpleProblemForm;
import ec.util.Parameter;
import ec.vector.IntegerVectorIndividual;

public class GAProblem extends Problem implements SimpleProblemForm {
	private static final long serialVersionUID = 1L;

	public static final String SENSORFILE = "sensorFile";
	public static final String TRACEFILE = "traceFile";
	public static final String TOPOLOGYFILE = "topologyFile";

	public File sensorFile;
	public File traceFile;
	public File topologyFile;

	public Topology topology;
	public Vector<Sensor> sensors;

	public FitnessFunction fitnessfunction;

	public void setup(final EvolutionState state, final Parameter base) {
		// very important, remember this
		super.setup(state, base);

		this.sensorFile = new File(state.parameters.getString(base
				.push(SENSORFILE), null));
		this.traceFile = new File(state.parameters.getString(base
				.push(TRACEFILE), null));
		this.topologyFile = new File(state.parameters.getString(base
				.push(TOPOLOGYFILE), null));

		FileReader fileReader = null;
		try {
			fileReader = new FileReader(this.traceFile, this.topologyFile,
					this.sensorFile);
			fileReader.readTraceFile();
			fileReader.readTopologyFile();
			fileReader.readSensorSettings();
			fileReader.process();
		} catch (SSIDException e) {
			state.output.fatal(e.getMessage());
		}

		this.topology = fileReader.getTopology();
		this.sensors = fileReader.getSensors();

		this.fitnessfunction = new FitnessFunction();
	}

	@Override
	public void describe(Individual ind, EvolutionState state,
			int subpopulation, int threadnum, int log, int verbosity) {
		// TODO Auto-generated method stub

	}

	@Override
	public void evaluate(EvolutionState state, Individual ind,
			int subpopulation, int threadnum) {
		if (ind.evaluated)
			return;

		if (!(ind instanceof IntegerVectorIndividual))
			state.output.fatal("Whoa!  It's not a IntegerVectorIndividual!!!",
					null);

		IntegerVectorIndividual ind2 = (IntegerVectorIndividual) ind;
		float rawfitness = 0;
		for (int x = 0; x < ind2.genome.length; x++) {
			ind2.genome[x] = Math.abs(ind2.genome[x]);
			ind2.genome[x] = ind2.genome[x] % this.topology.getNumberOfNodes();
		}

		for (int i = 0; i < this.sensors.size(); i++) {
			this.sensors.elementAt(i).setLocation(
					this.topology.nodes.getNode(ind2.genome[i]));
			this.sensors.elementAt(i).run();
		}

		this.fitnessfunction.checkContribution(sensors);
		rawfitness = this.fitnessfunction.evaluate(sensors);

		((SimpleFitness) ind2.fitness).setFitness(state, rawfitness, false);

		ind2.evaluated = true;
	}

}
